package MyLinkedList;

public class MyLinkedList implements LinkedList{

    static class Node {
        public Node prev;
        int data;
        public Node next;

        public Node() {
        }

        public Node(Node prev, int data, Node next) {
            this.prev = prev;
            this.data = data;
            this.next = next;
        }

    }

    private int size;
    private Node head;
    private Node tail;

    @Override
    public void addFirst(int data) {
        if (head == null) {
            head = new Node(null,data,null);
            tail = head;
        }else {
            Node addNode = new Node(null,data,head);
            head.prev = addNode;
            head = addNode;
        }
        size++;

    }

    @Override
    public void addLast(int data) {
        if (head == null) {
            head = new Node(null,data,null);
            tail = head;

        }else {
            Node addNode = new Node(tail,data,null);
            tail.next = addNode;
            tail = addNode;
        }
        size++;
    }

    @Override
    public boolean addIndex(int index, int data) {
        if (index < 0 || index > size) {
            throw new IndexException("index is access exceptions !!!");
        }

        if (index == 0) {
            addFirst(data);
            return true;
        }

        if (index == size) {
            addLast(data);
            return true;
        }

        Node p = head;
        for (int i = 0; i < index; i++) {
            p = p.next;
        }
        Node addIndex = new Node(p.prev,data,p);
        p.prev.next = addIndex;
        p.prev = addIndex;
        size++;

        return true;
    }

    @Override
    public boolean contain(int key) {
        if (head == null) {
            throw new NullPointerException("head is Null pointer Exception!!!");
        }
        Node p = head;
        while (p != null) {
            if (p.data == key) {
                return true;
            }
            p = p.next;
        }
        return false;
    }

    @Override
    public void remove(int key) {
        if (head == null) {
            throw new NullPointerException("head is Null pointer Exception!!!");
        }

        //头删节点
        if (head.data == key) {
            Node p = head.next;
            head.next = null;
            head = p;
            head.prev = null;
            size--;
            return;
        }

        //尾删节点
        if (tail.data == key) {
            Node p = tail.prev;
            tail.prev = null;
            tail = p;
            tail.next = null;
            size--;
            return;
        }

        Node p = head.next;
        while (p.next != null) {
            if (p.data == key) {
                Node prev = p.prev;
                Node next = p.next;
                prev.next = next;
                next.prev = prev;
                size--;
                return;
            }
            p = p.next;
        }
        throw new NotFoundException("未找到对应的节点进行删除!!!");
    }

    @Override
    public void removeAllKey(int key) {
        if (head == null) {
            throw new NullPointerException("head is Null pointer Exception!!!");
        }

        Node p = head.next;
        while (p.next != null) {
            if (p.data == key) {
                Node prev = p.prev;
                Node next = p.next;
                prev.next = next;
                next.prev = prev;
                size--;
            }
            p = p.next;
        }

        //头删节点
        if (head.data == key ) {
            Node pp = head.next;
            head.next = null;
            head = pp;
            head.prev = null;
            size--;
        }

        if (head == tail && head.data == key) {

            head = null;
            size--;
            return;
        }


        //尾删节点
        if (tail.data == key) {
            Node pp = tail.prev;
            tail.prev = null;
            tail = pp;
            tail.next = null;
            size--;

        }
    }

    @Override
    public int size() {
        return size;
    }

    @Override
    public void display() {
        Node p = head;
        while (p != null) {
            System.out.print(p.data + " ");
            p = p.next;
        }
        System.out.println();
    }

    @Override
    public void clear() {
        if (head == null){
            return;
        }
        size = 0;
        head = null;
        tail = null;
    }
}
